#pragma once

#include <gtl/type/type.h>

namespace gtl
{

namespace mpl
{

using namespace gtl::type;

template<class P1, class P2 = void_, class P3 = void_, class P4 = void_, class P5 = void_, 
					class P6 = void_, class P7 = void_, class P8 = void_, class P9 = void_>
struct nnary
{
	enum { typenum = 9 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
	typedef P5 type5th;
	typedef P6 type6th;
	typedef P7 type7th;
	typedef P8 type8th;
	typedef P9 type9th;
};

template<class P1>
struct nnary<P1, void_, void_, void_, void_, void_, void_, void_, void_>
{
	enum { typenum = 1 };
	typedef P1 type1st;
};

template<class P1, class P2>
struct nnary<P1, P2, void_, void_, void_, void_, void_, void_, void_>
{
	enum { typenum = 2 };
	typedef P1 type1st;
	typedef P2 type2nd;
};

template<class P1, class P2, class P3>
struct nnary<P1, P2, P3, void_, void_, void_, void_, void_, void_>
{
	enum { typenum = 3 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
};

template<class P1, class P2, class P3, class P4>
struct nnary<P1, P2, P3, P4, void_, void_, void_, void_, void_>
{
	enum { typenum = 4 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
};

template<class P1, class P2, class P3, class P4, class P5>
struct nnary<P1, P2, P3, P4, P5, void_, void_, void_, void_>
{
	enum { typenum = 5 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
	typedef P5 type5th;
};

template<class P1, class P2, class P3, class P4, class P5, class P6>
struct nnary<P1, P2, P3, P4, P5, P6, void_, void_, void_>
{
	enum { typenum = 6 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
	typedef P5 type5th;
	typedef P6 type6th;
};

template<class P1, class P2, class P3, class P4, class P5, class P6, class P7>
struct nnary<P1, P2, P3, P4, P5, P6, P7, void_, void_>
{
	enum { typenum = 7 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
	typedef P5 type5th;
	typedef P6 type6th;
	typedef P7 type7th;
};

template<class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
struct nnary<P1, P2, P3, P4, P5, P6, P7, P8, void_>
{
	enum { typenum = 8 };
	typedef P1 type1st;
	typedef P2 type2nd;
	typedef P3 type3th;
	typedef P4 type4th;
	typedef P5 type5th;
	typedef P6 type6th;
	typedef P7 type7th;
	typedef P8 type8th;
};

} // end of namespace mpl

} // end of namespace gtl